﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

using Qing.Lang;

namespace Qing.Std {

    class Quite : Native {
        public override string Name { get; set; } = "退出";
        public override string Desc { get; set; } = "可选参数1-整数，返回空；退出程序，如果传入参数1，则作为程序的退出码";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            if(args.Count > 0 && args[0].Tp == TP.Int) {
                Environment.Exit(args[0].Int());
            } else {
                Environment.Exit(0);
            }
            return new Expr(TP.None, null);
        }

    }

    class Print: Native {
        public override string Name { get; set; } = "显示";
        public override string Desc { get; set; } = "参数1-任意，返回空；显示参数1的格式化字符串";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            if (args.Count == 0) {
                return Expr.Err("显示函数调用参数不足");
            }

            if(Env.ConsoleGUI == null) {
                if (args[0].Tp == TP.Str) {
                    Console.WriteLine(args[0].Str());
                } else {
                    string str = args[0].ToStr();
                    Console.WriteLine(str);
                }
            } else {
                if (args[0].Tp == TP.Str) {
                    
                    Env.ConsoleGUI.ConsoleShow(args[0].Str(), 0);
                    
                } else {
                    string str = args[0].ToStr();

                    Env.ConsoleGUI.ConsoleShow(str, 0);
                }
            }

            
            
            return new Expr(TP.None, null);
        }

    }


    class Ask : Native {
        public override string Name { get; set; } = "获取输入";
        public override string Desc { get; set; } = "参数1-字符串，可选参数2-逻辑，返回字符串；参数1是提示文本，会在控制台输出，然后获取用户输入，参数2为真是是密码模式";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            if (args.Count == 0) {
                return Expr.Err("获取输入函数调用参数不足");
            }
            if (args[0].Tp != TP.Str) {
                return Expr.Err("获取输入函数提示文本必须为字符串");
            }
            Console.Write(args[0].Str());
            string inp = "";
            if (args.Count > 1 && args[1].ToBool()) {
                while (true) {
                    //存储用户输入的按键，并且在输入的位置不显示字符
                    ConsoleKeyInfo ck = Console.ReadKey(true);

                    //判断用户是否按下的Enter键
                    if (ck.Key != ConsoleKey.Enter) {
                        if (ck.Key != ConsoleKey.Backspace) {
                            //将用户输入的字符存入字符串中
                            inp += ck.KeyChar.ToString();
                            //将用户输入的字符替换为*
                            Console.Write("*");
                        } else {
                            if (inp.Length > 0) {
                                inp = inp.Remove(inp.Length - 1);
                                Console.Write("\b \b");
                            }
                        }
                    } else {
                        Console.WriteLine();
                        break;
                    }
                }
            } else {
                inp = Console.ReadLine() ?? "";
            }

            return new Expr(TP.Str, inp);
        }

    }


    class JGC : Native {
        public override string Name { get; set; } = "垃圾回收";
        public override string Desc { get; set; } = "无参，返回逻辑；主动调用一次垃圾回收";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            GC.Collect();

            return new Expr(TP.Bool, true);
        }
    }

    class Clear : Native {
        public override string Name { get; set; } = "清屏";
        public override string Desc { get; set; } = "无参，返回空；清空控制台上输出的内容";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            Console.Clear();

            return new Expr(TP.None, null);
        }

    }


    class CallCmd : Native {
        public override string Name { get; set; } = "调用命令";
        public override string Desc { get; set; } = "参数1-字符串，返回字符串；调用cmd命令";
        public override Expr Run(List<Expr> args, Ctx ctx, Obj? obj=null, List<Expr>? namedArgs=null) {
            if (args.Count > 0 && args[0].Tp == TP.Str) {
                Process CmdProcess = new Process();
                CmdProcess.StartInfo.FileName = "cmd.exe";
                CmdProcess.StartInfo.CreateNoWindow = true;         // 不创建新窗口    
                CmdProcess.StartInfo.UseShellExecute = false;       //不启用shell启动进程  
                CmdProcess.StartInfo.RedirectStandardInput = true;  // 重定向输入    
                CmdProcess.StartInfo.RedirectStandardOutput = true; // 重定向标准输出    
                CmdProcess.StartInfo.RedirectStandardError = true;  // 重定向错误输出  

                CmdProcess.StartInfo.Arguments = "/c " + args[0].Str();//“/C”表示执行完命令后马上退出  
                CmdProcess.Start();//执行  

                var str = CmdProcess.StandardOutput.ReadToEnd();//获取返回值  

                CmdProcess.WaitForExit();//等待程序执行完退出进程  

                CmdProcess.Close();//结束  

                return new Expr(TP.Str, str);
            }

            return Expr.Err("调用命令函数参数不足");
        }

    }


}
